home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / corelib / ncbimain.msw < prev    next >
Text File  |  1996-07-05  |  12KB  |  425 lines

  1. /*   ncbimain.c
  2. * ===========================================================================
  3. *
  4. *                            PUBLIC DOMAIN NOTICE                          
  5. *               National Center for Biotechnology Information
  6. *                                                                          
  7. *  This software/database is a "United States Government Work" under the   
  8. *  terms of the United States Copyright Act.  It was written as part of    
  9. *  the author's official duties as a United States Government employee and 
  10. *  thus cannot be copyrighted.  This software/database is freely available 
  11. *  to the public for use. The National Library of Medicine and the U.S.    
  12. *  Government have not placed any restriction on its use or reproduction.  
  13. *                                                                          
  14. *  Although all reasonable efforts have been taken to ensure the accuracy  
  15. *  and reliability of the software and data, the NLM and the U.S.          
  16. *  Government do not and cannot warrant the performance or results that    
  17. *  may be obtained by using this software or data. The NLM and the U.S.    
  18. *  Government disclaim all warranties, express or implied, including       
  19. *  warranties of performance, merchantability or fitness for any particular
  20. *  purpose.                                                                
  21. *                                                                          
  22. *  Please cite the author in any work or product based on this material.   
  23. *
  24. * ===========================================================================
  25. *
  26. * File Name:  ncbimain.c
  27. *
  28. * Author:  Ostell, Schuler
  29. *
  30. * Version Creation Date:   2/25/91
  31. *
  32. * Version Number:  1.1
  33. *
  34. * File Description: 
  35. *       portable main() and argc, argv handling
  36. *       Microsoft Windows version
  37. *
  38. * Modifications:  
  39. * --------------------------------------------------------------------------
  40. * Date     Name        Description of modification
  41. * -------  ----------  -----------------------------------------------------
  42. * 2/25/91  Ostell      add support to GetArgs for args separated from tags
  43. *
  44. * ==========================================================================
  45. */
  46.  
  47. #include <ncbi.h>
  48. #include <ncbiwin.h>
  49. #include "ncbirc.h"
  50.  
  51. #define MAX_ARGS 50       /* maximum args this can process */
  52.  
  53. #define WM_CALLMAIN (WM_USER+1)
  54.  
  55. extern char NEAR sProgramName[];
  56. static char  winfile[128];
  57. static char  winargs[128];
  58. static char *targv[MAX_ARGS];
  59. static int   targc;
  60. static HWND  hWnd;
  61. static HANDLE  hIconProgram;
  62. static HANDLE  hIconNcbiLogo;
  63. static short   xScreen, yScreen;
  64. static short   xChar, yChar;
  65. static short   xIcon, yIcon;
  66.  
  67. BOOL NEAR InitWindows(HINSTANCE,HINSTANCE,LPSTR,int);
  68. void NEAR CenterWindow(HWND);
  69. long FAR PASCAL  FrameWndProc(HWND,unsigned,UINT,LONG);
  70.  
  71. /*****************************************************************************
  72. *
  73. *   main()
  74. *     this replaces the normal program main()
  75. *     handles argc and argv
  76. *     does any required windows initialization
  77. *
  78. *****************************************************************************/
  79.  
  80. int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
  81.  
  82. {
  83.     MSG    msg;
  84.     Nlm_Int2  retval;
  85.  
  86.     InitWindows(hInstance, hPrevInst, lpCmdLine, nCmdShow);
  87.  
  88.     while(GetMessage(&msg, NULL, 0, 0))  {
  89.         TranslateMessage(&msg);
  90.         DispatchMessage(&msg);
  91.     }
  92.     Nlm_FreeConfigStruct ();
  93.     retval = (Nlm_Int2) msg.wParam;
  94.     return  retval;
  95. }
  96.  
  97. BOOL NEAR InitWindows (HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
  98.  
  99. {
  100.     WNDCLASS  wc;
  101.     int       i=0;
  102.     char      *p;
  103.     long      lUnits;
  104.  
  105.     /* get some system dimensions */
  106.     lUnits  = GetDialogBaseUnits();
  107.     xChar   = LOWORD(lUnits);
  108.     yChar   = HIWORD(lUnits);
  109.     xScreen = GetSystemMetrics(SM_CXSCREEN);
  110.     yScreen = GetSystemMetrics(SM_CYSCREEN);
  111.     xIcon   = GetSystemMetrics(SM_CXICON);
  112.     yIcon   = GetSystemMetrics(SM_CYICON);
  113.  
  114.     /* load resources */
  115.     LoadString(hInstance, STR_PROGRAM, sProgramName, 16);
  116.     hIconProgram  = LoadIcon(hInstance, MAKEINTRESOURCE(ICO_PROGRAM));
  117.     hIconNcbiLogo = LoadIcon(hInstance, MAKEINTRESOURCE(ICO_NCBILOGO));
  118.  
  119.     /* initialize targc and targv */
  120.     StringCpy(winargs, lpCmdLine);
  121.     GetModuleFileName(hInstance, winfile, sizeof winfile);
  122.     targv[i++] = winfile;
  123.     if (winargs[0]) {
  124.         targv[i++] = winargs;
  125.         for(p=winargs; *p; p++) {
  126.             if (*p == ' ') {
  127.                 while (*p && *p == ' ')  *p++ = '\0';
  128.                 if (*p) targv[i++] = p;
  129.             }
  130.         }
  131.     }
  132.     targc = i;
  133.  
  134.     /* register windows class */
  135.     if (!hPrevInst) {
  136.         wc.style         = CS_HREDRAW | CS_VREDRAW;
  137.         wc.lpfnWndProc   = FrameWndProc;
  138.         wc.cbClsExtra    = 0;
  139.         wc.cbWndExtra    = 0;
  140.         wc.hInstance     = hInstance;
  141.         wc.hIcon         = hIconProgram;
  142.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  143.         wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
  144.         wc.lpszMenuName  = NULL;
  145.         wc.lpszClassName = sProgramName;
  146.  
  147.         if (!RegisterClass (&wc))
  148.             return (FALSE);
  149.     }
  150.  
  151.     /* create window */
  152.     hWnd = CreateWindow(sProgramName, "", WS_OVERLAPPED,
  153.                 0, 0, 20*xChar, 2*(yIcon+yChar), 
  154.                 NULL, NULL, hInstance, NULL);
  155.     if (!IsWindow(hWnd))
  156.         return(FALSE);
  157.     CenterWindow(hWnd);
  158.     ShowWindow(hWnd, nCmdShow);
  159.     UpdateWindow(hWnd);
  160.  
  161.     /* tell the window to call Nlm_Main() */
  162.     PostMessage(hWnd, WM_CALLMAIN, 0, 0);
  163.     return(TRUE);
  164. }
  165.  
  166. void NEAR  CenterWindow (HWND hWnd)
  167.  
  168. {
  169.   RECT rWnd;
  170.   int  xWnd, yWnd;
  171.  
  172.   GetWindowRect(hWnd, &rWnd);
  173.   xWnd = rWnd.right - rWnd.left;
  174.   yWnd = rWnd.bottom - rWnd.top;
  175.   MoveWindow(hWnd, (xScreen-xWnd)/2, (yScreen-yWnd)/2, xWnd, yWnd, FALSE);
  176. }
  177.  
  178. long FAR PASCAL  FrameWndProc (HWND hWnd, unsigned wMsg, UINT wParam, LONG lParam)
  179.  
  180. {
  181.     static int  retval;
  182.     static int  x, y;
  183.     PAINTSTRUCT ps;
  184.     HANDLE      hDC;
  185.     HANDLE      hCursor;
  186.  
  187.     switch(wMsg) {
  188.  
  189.         case WM_CREATE:
  190.             x = 10*xChar;
  191.             y = yChar/2;
  192.             return(0);
  193.  
  194.         case WM_PAINT:
  195.             hDC = BeginPaint(hWnd, &ps);
  196.             DrawIcon(hDC, x-xIcon/2, y, hIconProgram);
  197.             SetTextAlign(hDC, TA_CENTER);
  198.             TextOut(hDC, x, y+yIcon, sProgramName, lstrlen(sProgramName));
  199.             EndPaint(hWnd, &ps);
  200.             return(0);
  201.  
  202.         case WM_CALLMAIN:
  203.             hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));
  204.             retval = Nlm_Main();
  205.             DestroyWindow(hWnd);
  206.             SetCursor(hCursor);
  207.             return(0);
  208.  
  209.         case WM_DESTROY:
  210.             PostQuitMessage(retval);
  211.             return(0);
  212.     }
  213.     return  DefWindowProc(hWnd, wMsg, wParam, lParam);
  214. }
  215.  
  216.  
  217. /*****************************************************************************
  218. *
  219. *   Nlm_GetArgs(ap)
  220. *       returns user startup arguments
  221. *
  222. *****************************************************************************/
  223.  
  224. Nlm_Boolean  Nlm_GetArgs (Nlm_CharPtr progname, Nlm_Int2 numargs, Nlm_ArgPtr ap)
  225. {
  226.     Nlm_Boolean okay = FALSE, all_default = TRUE, range;
  227.     Nlm_Int2 i, j;
  228.     Nlm_Int4 ifrom, ito;
  229.     Nlm_FloatHi ffrom, fto;
  230.     Nlm_ArgPtr curarg;
  231.     Nlm_Boolean resolved[MAX_ARGS];
  232.     char *arg;
  233.     Nlm_Char tmp;
  234.     Nlm_Boolean ok;
  235.  
  236.     if ((ap == NULL) || (numargs == 0) || (numargs > MAX_ARGS))
  237.         return okay;
  238.  
  239.     curarg = ap;                        /* set defaults */
  240.     Nlm_MemFill(resolved, '\0', (MAX_ARGS * sizeof(Nlm_Boolean)));
  241.  
  242.     for (i = 0; i < numargs; i++, curarg++)
  243.     {
  244.         if ((curarg->type < ARG_BOOLEAN) ||
  245.              (curarg->type > ARG_DATA_OUT))
  246.         {
  247.             Message(MSG_ERROR, "Invalid Arg->type in %s", curarg->prompt);
  248.             return okay;
  249.         }
  250.         curarg->intvalue = 0;
  251.         curarg->floatvalue = 0.0;
  252.         curarg->strvalue = NULL;
  253.         if (curarg->defaultvalue != NULL)
  254.         {
  255.             resolved[i] = TRUE;
  256.             switch (curarg->type)
  257.             {
  258.                 case ARG_BOOLEAN:
  259.                     if (TO_UPPER(*curarg->defaultvalue) == 'T')
  260.                         curarg->intvalue = 1;
  261.                     else
  262.                         curarg->intvalue = 0;
  263.                     break;
  264.                 case ARG_INT:
  265.                     sscanf(curarg->defaultvalue, "%ld", &curarg->intvalue);
  266.                     break;
  267.                 case ARG_FLOAT:
  268.                     sscanf(curarg->defaultvalue, "%lf", &curarg->floatvalue);
  269.                     break;
  270.                 case ARG_STRING:
  271.                 case ARG_FILE_IN:
  272.                 case ARG_FILE_OUT:
  273.                 case ARG_DATA_IN:
  274.                 case ARG_DATA_OUT:
  275.                     curarg->strvalue = StringSave (curarg->defaultvalue);
  276.                     break;
  277.             }
  278.         }
  279.         else if (curarg->optional == FALSE)
  280.             all_default = FALSE;    /* must have some arguments */
  281.     }
  282.                           /**** show usage if no args on command line ***/
  283.     if ((targc == 1) && (all_default == TRUE))   /* no args ok */
  284.         return TRUE;
  285.  
  286.     if ((targc == 1) || (*(targv[1]+1) == '\0'))
  287.     {
  288.         Message(MSG_ERROR, "No arguments given");
  289.         return okay;
  290.     }
  291.  
  292.     for (i = 1; i < targc; i++)
  293.     {
  294.         arg = targv[i];
  295.         if (*arg != '-')
  296.         {
  297.             Message(MSG_ERROR, "Arguments must start with -");
  298.             return okay;
  299.         }
  300.         arg++;
  301.         curarg = ap;
  302.         for (j = 0; j < numargs; j++, curarg++)
  303.         {
  304.             if (*arg == curarg->tag)
  305.                 break;
  306.         }
  307.         if (j == numargs)
  308.         {
  309.             Message(MSG_ERROR, "Invalid argument: %s", targv[i]);
  310.             return okay;
  311.         }
  312.         arg++;
  313.         if (*arg == '\0')
  314.         {
  315.             ok = FALSE;
  316.             if ((i + 1) < targc)  /* argument comes after space */
  317.             {
  318.                 if (*targv[i + 1] == '-')
  319.                 {
  320.                     tmp = *(targv[i+1]+1);
  321.                     if (((curarg->type == ARG_INT) || (curarg->type == ARG_FLOAT)) &&
  322.                         ((tmp == '.') || (IS_DIGIT(tmp))))
  323.                         ok = TRUE;
  324.                 }
  325.                 else
  326.                     ok = TRUE;
  327.                 if (ok)
  328.                 {
  329.                     i++;
  330.                     arg = targv[i];
  331.                 }
  332.             }
  333.  
  334.             if ((!ok) && (curarg->type != ARG_BOOLEAN))
  335.             {
  336.                 Message(MSG_ERROR, "No argument given for %s", curarg->prompt);
  337.                 return okay;
  338.             }
  339.         }
  340.         resolved[j] = TRUE;
  341.         switch (curarg->type)
  342.         {
  343.             case ARG_BOOLEAN:
  344.                 if (TO_UPPER(*arg) == 'T')
  345.                     curarg->intvalue = 1;
  346.                 else if (TO_UPPER(*arg) == 'F')
  347.                     curarg->intvalue = 0;
  348.                 else if (*arg == '\0')
  349.                     curarg->intvalue = 1;
  350.                 break;
  351.             case ARG_INT:
  352.                 sscanf(arg, "%ld", &curarg->intvalue);
  353.                 if ((curarg->from != NULL) || (curarg->to != NULL))
  354.                 {
  355.                     range = TRUE;
  356.                     if (curarg->from != NULL)
  357.                     {
  358.                         sscanf(curarg->from, "%ld", &ifrom);
  359.                         if (curarg->intvalue < ifrom)
  360.                             range = FALSE;
  361.                     }
  362.                     if (curarg->to != NULL)
  363.                     {
  364.                         sscanf(curarg->to, "%ld", &ito);
  365.                         if (curarg->intvalue > ito)
  366.                             range = FALSE;
  367.                     }
  368.                     if (! range)
  369.                     {
  370.                         Message(MSG_ERROR, "%s [%ld] is out of range [%s to %s]", curarg->prompt,
  371.                             curarg->intvalue, curarg->from, curarg->to);
  372.                         return okay;
  373.                     }
  374.                 }
  375.                 break;
  376.             case ARG_FLOAT:
  377.                 sscanf(arg, "%lf", &curarg->floatvalue);
  378.                 if ((curarg->from != NULL) || (curarg->to != NULL))
  379.                 {
  380.                     range = TRUE;
  381.                     if (curarg->from != NULL)
  382.                     {
  383.                         sscanf(curarg->from, "%lf", &ffrom);
  384.                         if (curarg->floatvalue < ffrom)
  385.                             range = FALSE;
  386.                     }
  387.                     if (curarg->to != NULL)
  388.                     {
  389.                         sscanf(curarg->to, "%lf", &fto);
  390.                         if (curarg->floatvalue > fto)
  391.                             range = FALSE;
  392.                     }
  393.                     if (! range)
  394.                     {
  395.                         Message(MSG_ERROR, "%s [%g] is out of range [%s to %s]", curarg->prompt, 
  396.                             curarg->floatvalue, curarg->from, curarg->to);
  397.                         return okay;
  398.                     }
  399.                 }
  400.                 break;
  401.             case ARG_STRING:
  402.             case ARG_FILE_IN:
  403.             case ARG_FILE_OUT:
  404.             case ARG_DATA_IN:
  405.             case ARG_DATA_OUT:
  406.                 curarg->strvalue = StringSave (arg);
  407.                 break;
  408.         }    /*** end switch ****/
  409.     }       
  410.     curarg = ap;
  411.     okay = TRUE;
  412.     for (i = 0; i < numargs; i++, curarg++)
  413.     {
  414.         if ((! curarg->optional) && (! resolved[i]))
  415.         {
  416.             Message(MSG_ERROR, "%s was not given an argument", curarg->prompt);
  417.             okay = FALSE;
  418.         }
  419.     }
  420.     return okay;
  421. }
  422.  
  423.  
  424.  
  425.